
use libc::{uint32_t, uint64_t};
use std::os::raw::{c_double, c_int, c_uint};
unsafe extern "C" {
    // 使用 libc 类型定义函数签名
    pub unsafe fn xplusy(x: libc::c_double, y: libc::c_double) -> libc::c_double;
    pub unsafe fn xmuly(x: libc::c_double, y: libc::c_double) -> libc::c_double;

    //////////////
    unsafe fn fibonacci(n: uint32_t) -> uint64_t;
    unsafe fn is_prime(n: uint32_t) -> c_int;
    unsafe fn gcd(a: uint32_t, b: uint32_t) -> uint32_t;
    unsafe fn vector_add(a: *const c_double, b: *const c_double, c: *mut c_double, size: uint32_t);
}

/* 包装成 safe 函数 */
pub fn xplusy_safe(x: f64, y: f64) -> f64 {
    unsafe { xplusy(x, y) }
}

/* 包装成 safe 函数 */
pub fn xmuly_safe(x: f64, y: f64) -> f64 {
    unsafe { xmuly(x, y) }
}

//////////////////////

// Rust 包装器，提供更安全的接口
pub struct MathUtils;

impl MathUtils {
    pub fn fibonacci(n: u32) -> u64 {
        unsafe { fibonacci(n) }
    }

    pub fn is_prime(n: u32) -> bool {
        unsafe { is_prime(n) != 0 }
    }

    pub fn gcd(a: u32, b: u32) -> u32 {
        unsafe { gcd(a, b) }
    }

    pub fn vector_add(a: &[f64], b: &[f64]) -> Vec<f64> {
        assert_eq!(a.len(), b.len(), "Vectors must have the same length");

        let size = a.len() as u32;
        let mut result = vec![0.0; a.len()];

        unsafe {
            vector_add(a.as_ptr(), b.as_ptr(), result.as_mut_ptr(), size);
        }

        result
    }
}
